#include "CallPutCombinationsAnalysis.h"

#include "StockCallPutCombinations.h"

#include <cmath>

namespace
{
    const double epsilon = 0.00001;
    bool doubleEquals(double left, double right ) {
      return (fabs(left - right) < epsilon);
    }

    bool doubleLess(double left, double right, bool orequal = false) {
      if (fabs(left - right) < epsilon) {
        return (orequal);
      }
      return (left < right);
    }

    bool doubleGreater(double left, double right, bool orequal = false) {
      if (fabs(left - right) < epsilon) {
        return (orequal);
      }
      return (left > right);
    }
}

CallPutCombinationsAnalysis::CallPutCombinationsAnalysis( const std::string& separator, const std::string& outputFilePath )
: m_separator( separator ),
  m_callPutMap( ),
  m_outputFile( )
{

    m_outputFile.open( outputFilePath );
    StockCallPutCombinations::PrintFirstRow( separator, m_outputFile );
}

CallPutCombinationsAnalysis::~CallPutCombinationsAnalysis( )
{
    for( MapIterator it = m_callPutMap.begin();
         it != m_callPutMap.end(); ++it )
    {
        delete it->second;
    }
    m_outputFile.close( );
}

void CallPutCombinationsAnalysis::AddWarrant( const Warrant& warrant )
{
    if( !doubleEquals( warrant.m_lastPrice, 0.0 ) )
    {
        MapIterator it = m_callPutMap.find( warrant.m_stockId );
        if( it != m_callPutMap.end() )
        {
            it->second->AddWarrant( warrant );
        }
        else
        {
            StockCallPutCombinations* callPutCombinations = new StockCallPutCombinations( m_separator, warrant.m_stockId );
            std::pair<MapIterator, bool> ret = m_callPutMap.insert( MapPair( warrant.m_stockId, callPutCombinations ) );
        
            ret.first->second->AddWarrant( warrant );
        }
    }
}

void CallPutCombinationsAnalysis::PrintCombinations( )
{
    for( MapIterator it = m_callPutMap.begin();
         it != m_callPutMap.end(); ++it )
    {
        it->second->PrintCombinations( m_outputFile );
    }
}
